package top.techqi.app.mcs51.usbdlk

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import android.os.Bundle
import android.view.View
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import com.google.android.material.tabs.TabLayoutMediator
import top.techqi.app.mcs51.R
import top.techqi.app.mcs51.databinding.FragmentUsbdlkMainBinding
import top.techqi.app.mcs51.usbdlk.vm.UsbdlkViewModel
import top.techqi.core.base.BaseFragment
import top.techqi.usbd.UsbProber
import top.techqi.view.viewpager2.DataFragmentStateAdapter

class UsbdlkMainFragment : BaseFragment<FragmentUsbdlkMainBinding>(
    FragmentUsbdlkMainBinding::inflate
) {
    private val vmUsbdlk by viewModels<UsbdlkViewModel>()

    private lateinit var subPagerAdapter: SubPagerAdapter

    private val usbReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            when (intent.action) {
                UsbManager.ACTION_USB_DEVICE_ATTACHED,
                UsbManager.ACTION_USB_DEVICE_DETACHED -> {
                    vmUsbdlk.scanDevices()
                }
            }
        }
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)

        val filter = IntentFilter()
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED)
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
        ContextCompat.registerReceiver(
            context, usbReceiver, filter,
            ContextCompat.RECEIVER_EXPORTED
        )

        vmUsbdlk.scanDevices()
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        subPagerAdapter = SubPagerAdapter(this)
        binding.vpgPager.adapter = subPagerAdapter
        TabLayoutMediator(binding.tabPager, binding.vpgPager) { tab, position ->
            when (position) {
                0 -> tab.text = getText(R.string.tab_main_label_usbdlk_list)
                else -> {
                    val (device, intfId) = vmUsbdlk.devicesOpen.value
                        ?.getOrNull(position - 1) ?: return@TabLayoutMediator
                    tab.text = UsbProber.detectDrivers(device).get(intfId)?.first
                }
            }
        }.attach()

        vmUsbdlk.devicesOpen.observe(viewLifecycleOwner) { value ->
            val data = ArrayList<Any>(value)
            data.add(0, UsbdlkListFragment.TAG)
            subPagerAdapter.commit(data)
        }
        vmUsbdlk.deviceAwait.observe(viewLifecycleOwner) { value ->
            value ?: return@observe
            val devicesOpenValue = vmUsbdlk.devicesOpen.value ?: return@observe
            val index = devicesOpenValue.indexOfFirst { (device, intfId) ->
                device == value.first && intfId == value.second
            }
            binding.vpgPager.setCurrentItem(index + 1, true)
            vmUsbdlk.deviceAwait.value = null
        }
    }

    override fun onDetach() {
        context?.unregisterReceiver(usbReceiver)
        super.onDetach()
    }

    class SubPagerAdapter(fragment: Fragment) : DataFragmentStateAdapter<Any>(fragment) {
        override fun createFragment(position: Int): Fragment {
            return when (val item = data[position]) {
                UsbdlkListFragment.TAG -> UsbdlkListFragment()
                is Pair<*, *> -> {
                    @Suppress("UNCHECKED_CAST")
                    if (item.first is UsbDevice && item.second is Int) {
                        val (device, intfId) = item as Pair<UsbDevice, Int>
                        UsbdlkUartFragment.newInstance(device, intfId)
                    } else {
                        Fragment()
                    }
                }

                else -> Fragment()
            }
        }
    }
}
